package com.kfm.base.reflect;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class Demo02 {

    public static void main(String[] args) {
        Class<Student> studentClass = Student.class;
        Method[] allMethod = getAllMethod2(studentClass);

        for (Method method : allMethod){
            System.out.println(method);
        }

    }

    /**
     * 返回类中所有的方法
     *  1. 类中声明的方法
     *  2. 可以从父类中继承的方法(非私有方法)
     * @param cla
     * @return
     */
    public static Method[]  getAllMethod(Class cla){
        // 保存所有的方法
        List<Method> result = new ArrayList<>();
        // 1. 获取类中声明的方法
        Method[] methods = cla.getDeclaredMethods();
        result.addAll(List.of(methods));

        // 2. 获取父类中的方法
        List<Method> parentMethod = getParentMethod(cla);

        // 添加到结果集中
        result.addAll(parentMethod);

        return result.toArray(new Method[]{});
    }

    public static Method[]  getAllMethod2(Class cla){
        // 保存所有的方法
        Set<Method> result = new HashSet<>();
        // 1. 获取类中声明的方法
        Method[] methods = cla.getDeclaredMethods();
        result.addAll(List.of(methods));

        // 2. 获取public的方法
        Method[] publilcMethod = cla.getMethods();

        // 添加到结果集中
        result.addAll(List.of(publilcMethod));

        return result.toArray(new Method[]{});
    }
    private static List<Method> getParentMethod(Class subClass){
        List<Method> result = new ArrayList<>();
        Class superclass = subClass.getSuperclass();
        if (superclass != null){ // 有父类
            // 1. 获取父类的所有方法
            Method[] superMethods = superclass.getDeclaredMethods();
            // 3. 排除私有方法
//        Object[] array = Arrays.stream(superMethods)
//                .filter(method -> !Modifier.isPrivate(method.getModifiers()))
//                .toArray();
            // 遍历父类中的方法
            for (int i = 0; i < superMethods.length; i ++){
                int modifiers = superMethods[i].getModifiers();
                // 判断是否是私有方法
                if (!Modifier.isPrivate(modifiers)){
                    // 不是私有方法
                    result.add(superMethods[i]);
                }
            }
            // 2. 获取父类的父类的方法
            List<Method> parentMethod = getParentMethod(superclass);
            result.addAll(parentMethod);
        }
        return result;
    }

    private static List<Method> getParentMethod2(Class subClass){
        List<Method> result = new ArrayList<>();
        Class superclass = subClass.getSuperclass();
        while (superclass != null){ // 有父类
            // 1. 获取父类的所有方法
            Method[] superMethods = superclass.getDeclaredMethods();
            // 3. 排除私有方法
//        Object[] array = Arrays.stream(superMethods)
//                .filter(method -> !Modifier.isPrivate(method.getModifiers()))
//                .toArray();
            // 遍历父类中的方法
            for (int i = 0; i < superMethods.length; i ++){
                int modifiers = superMethods[i].getModifiers();
                // 判断是否是私有方法
                if (!Modifier.isPrivate(modifiers)){
                    // 不是私有方法
                    result.add(superMethods[i]);
                }
            }

            // 2. 获取父类的父类的方法
            superclass = superclass.getSuperclass();
        }
        return result;
    }
}
